//Date: 2023-11-03 20:02:10
//LastEditors: jie zhengjie_liang@qq.com
//LastEditTime: 2023-11-26 00:20:51
//FilePath: /photowall/pkg/pkg/pkg/main/router/wechat_login.go

package router

import (
	"fmt"
	"math"
	"net/http"
	"photowall/pkg/config"
	"photowall/pkg/log"
	"photowall/pkg/optiondef"

	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
	"github.com/gin-gonic/gin"
)

func init() {
	wxLoginRouteRegister()
}

//description: route定义
//return {*}

func wxLoginRouteRegister() {
	router := GetMainRouter()

	store := cookie.NewStore([]byte("secret_key")) // 使用一个密钥来加密 cookie
	router.Use(sessions.Sessions("my_session", store))

	router.GET("/test/", func(c *gin.Context) {
		c.JSON(http.StatusAccepted, gin.H{
			"hello": "test",
		})
	})

	router.POST("/photowall/wxuser/login/:js_code", wxLogginRoute)
	router.GET("/photowall/wxuser/userinfo", checkWechatUserLoggedMiddleWare, getWxUserInfoRoute)
	router.POST("/photowall/wxuser/islogin", isWxUserLoggedRoute)
	router.POST("/photowall/wxuser/logout", loggoutWxuserRoute)
}

//description: 进行登录操作
//param {*gin.Context} ctx
//return {*}

func wxLogginRoute(c *gin.Context) {
	sessionMark := config.GetConfig().WechatUserConfig.RouteSession
	// seesionExpireTime := config.GetConfig().WechatUserConfig.RedisSessionExpiretime

	session, err := c.Cookie(sessionMark)
	if err == nil {
		logged, _ := optiondef.GetWxUserService().WxIsUserLogged(&optiondef.WxRegisterLoginInfo{Session: session})
		if logged {
			c.JSON(http.StatusAccepted, gin.H{
				"msg":    "you have logged!",
				"status": 201,
			})
			return
		}
	}

	jsCode := c.Param("js_code")
	if jsCode == "" {
		c.JSON(http.StatusAccepted, gin.H{
			"msg":    "logging failed",
			"status": 400,
		})
		return
	}

	session, err = optiondef.GetWxUserService().WxLoginUser(&optiondef.WxRegisterLoginInfo{Jscode: jsCode})
	if err != nil {
		log.GetMainLogger().Info(fmt.Sprintf("func routerJsCodeProc: can not get session, err is:%v", err.Error()))
		c.JSON(http.StatusBadGateway, gin.H{
			"msg":    "failed",
			"status": 500,
		})
		return
	}
	if len(session) == 0 {
		log.GetMainLogger().Info("func routerJsCodeProc: get null serssion")
		c.JSON(http.StatusBadGateway, gin.H{
			"msg":    "failed",
			"status": 500,
		})
		return
	}

	c.SetCookie(sessionMark, session, math.MaxInt32, "/", "", false, false)
	c.JSON(http.StatusAccepted, gin.H{
		"msg":    "you are logging!",
		"status": 200,
	})
}

// checkWechatUserLoggedMiddleWare 登录校验中间件，未登录会直接返回
func checkWechatUserLoggedMiddleWare(c *gin.Context) {
	// 获取配置中的 session mark
	sessionMark := config.GetConfig().WechatUserConfig.RouteSession

	// 从 cookie 中获取 session
	session, err := c.Cookie(sessionMark)
	if err != nil {
		// 如果获取 session 失败，返回未授权状态
		c.JSON(http.StatusUnauthorized, gin.H{
			"msg":    "require logging",
			"status": http.StatusUnauthorized,
		})
		c.Abort()
		return
	}

	// 检查用户是否已登录
	logged, err := optiondef.GetWxUserService().WxIsUserLogged(&optiondef.WxRegisterLoginInfo{Session: session})
	if err != nil {
		// 如果检查登录状态失败，记录错误并返回内部错误状态
		log.GetMainLogger().Error("func WxIsUserLogged failed: ", session, err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{
			"msg":    "internal error",
			"status": http.StatusInternalServerError,
		})
		c.Abort()
		return
	}

	// 如果用户未登录，返回未授权状态
	if !logged {
		c.JSON(http.StatusUnauthorized, gin.H{
			"msg":    "require logging",
			"status": http.StatusUnauthorized,
		})
		c.Abort()
		return
	}

	// 用户已登录，继续处理请求
	c.Next()
}

func getWxUserInfoRoute(c *gin.Context) {
	session_mark := config.GetConfig().WechatUserConfig.RouteSession

	session, err := c.Cookie(session_mark)
	if err != nil {
		c.JSON(http.StatusUnauthorized, gin.H{
			"msg":    "require logging",
			"status": 401,
		})

		c.Abort()
	}

	res, err := optiondef.GetWxUserService().WxGetUserinfo(&optiondef.WxRegisterLoginInfo{Session: session})
	if err != nil {
		log.GetMainLogger().Error(fmt.Sprintf(`cat not get user info, %v`, err))
		c.JSON(http.StatusBadGateway, gin.H{
			"msg":    "internal error",
			"status": 500,
		})
		c.Abort()
	}

	c.JSON(http.StatusAccepted, *res)
}

func isWxUserLoggedRoute(c *gin.Context) {
	sessionMark := config.GetConfig().WechatUserConfig.RouteSession

	session, err := c.Cookie(sessionMark)
	if err == nil {
		logged, _ := optiondef.GetWxUserService().WxIsUserLogged(&optiondef.WxRegisterLoginInfo{Session: session})
		if logged {
			c.JSON(http.StatusAccepted, gin.H{
				"msg":    "you have logged!",
				"status": 201,
			})
			return
		}
	}

	c.JSON(http.StatusNotFound, gin.H{
		"msg":    "you have not logged",
		"status": 400,
	})
}

func loggoutWxuserRoute(c *gin.Context) {
	sessionMark := config.GetConfig().WechatUserConfig.RouteSession

	session, err := c.Cookie(sessionMark)
	if err != nil {
		c.JSON(http.StatusAccepted, gin.H{
			"msg":    "you have logout",
			"status": 200,
		})
	}

	ok, _ := optiondef.GetWxUserService().WxLogoutUser(&optiondef.WxRegisterLoginInfo{Session: session})
	if ok {
		c.JSON(http.StatusAccepted, gin.H{
			"msg":    "you have logout!",
			"status": 200,
		})
		return
	}

	c.JSON(http.StatusBadGateway, gin.H{
		"msg":    "failed",
		"status": 500,
	})
}
